package com.petdog.module.tools.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.petdog.common.constant.ResponseCode;
import com.petdog.common.dto.ResponseDTO;
import com.petdog.common.exception.BusinessException;
import com.petdog.module.tools.dto.BehaviorGuideDTO;
import com.petdog.module.tools.dto.BehaviorWikiDTO;
import com.petdog.module.tools.dto.GetBehaviorGuidesRequest;
import com.petdog.module.tools.dto.SearchBehaviorGuideRequest;
import com.petdog.module.tools.service.BehaviorGuideService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/api/tools")
public class BehaviorGuideController {

    @Autowired
    private BehaviorGuideService behaviorGuideService;

    /**
     * 获取指南列表
     */
    @GetMapping("/behavior-guides")
    public ResponseDTO<Page<BehaviorGuideDTO>> getBehaviorGuides(@Valid GetBehaviorGuidesRequest request) {
        try {
            Page<BehaviorGuideDTO> guides = behaviorGuideService.getBehaviorGuides(request);
            return ResponseDTO.success(guides, "加载成功");
        } catch (Exception e) {
            return ResponseDTO.fail(ResponseCode.SERVER_ERROR, "加载失败，请重试");
        }
    }

    /**
     * 获取指南详情
     */
    @GetMapping("/behavior-detail/{id}")
    public ResponseDTO<BehaviorGuideDTO> getBehaviorGuideDetail(@PathVariable("id") Long guideId) {
        try {
            // 校验ID格式
            if (guideId == null || guideId <= 0) {
                throw new BusinessException(ResponseCode.PARAM_ERROR, "内容ID格式错误");
            }
            
            BehaviorGuideDTO guide = behaviorGuideService.getBehaviorGuideDetail(guideId);
            if (guide == null) {
                throw new BusinessException(ResponseCode.NOT_FOUND, "该内容已下架或不存在");
            }
            
            // 记录用户浏览历史（如果用户已登录）
            Long userId = getCurrentUserId(); // 假设从会话中获取用户ID
            if (userId != null) {
                behaviorGuideService.recordUserHistory(userId, guideId);
            }
            
            return ResponseDTO.success(guide, "加载成功");
        } catch (BusinessException e) {
            return ResponseDTO.fail(e.getCode(), e.getMessage());
        } catch (Exception e) {
            return ResponseDTO.fail(ResponseCode.SERVER_ERROR, "加载失败，请重试");
        }
    }

    /**
     * 搜索行为指南
     */
    @GetMapping("/behavior-search")
    public ResponseDTO<Page<BehaviorGuideDTO>> searchBehaviorGuides(@Valid SearchBehaviorGuideRequest request) {
        try {
            // 校验关键词
            String keyword = request.getKeyword();
            if (keyword == null || keyword.trim().isEmpty()) {
                return ResponseDTO.fail(ResponseCode.PARAM_ERROR, "请输入搜索关键词");
            }
            
            // 校验关键词长度
            if (keyword.length() < 1 || keyword.length() > 20) {
                return ResponseDTO.fail(ResponseCode.PARAM_ERROR, "关键词长度需在1-20字符内");
            }
            
            // 过滤敏感词（这里只是示例，实际应该调用敏感词过滤服务）
            if (containsSensitiveWords(keyword)) {
                return ResponseDTO.fail(ResponseCode.PARAM_ERROR, "搜索关键词含敏感内容，请修正后重试");
            }
            
            // 过滤SQL注入和XSS攻击脚本
            if (containsMaliciousCode(keyword)) {
                return ResponseDTO.fail(ResponseCode.PARAM_ERROR, "关键词含非法内容");
            }
            
            Page<BehaviorGuideDTO> result = behaviorGuideService.searchBehaviorGuides(request);
            if (result.getTotal() == 0) {
                return ResponseDTO.success(result, "暂无相关内容，请尝试其他关键词");
            }
            
            return ResponseDTO.success(result, "搜索成功");
        } catch (BusinessException e) {
            return ResponseDTO.fail(e.getCode(), e.getMessage());
        } catch (Exception e) {
            return ResponseDTO.fail(ResponseCode.SERVER_ERROR, "搜索失败，请重试");
        }
    }

    /**
     * 获取所有行为标签
     */
    @GetMapping("/behavior-tags")
    public ResponseDTO<List<String>> getAllTags() {
        try {
            List<String> tags = behaviorGuideService.getAllTags().stream()
                    .map(tag -> tag.getTagName())
                    .toList();
            return ResponseDTO.success(tags, "加载成功");
        } catch (Exception e) {
            return ResponseDTO.fail(ResponseCode.SERVER_ERROR, "加载失败，请重试");
        }
    }

    /**
     * 获取热门指南
     */
    @GetMapping("/behavior-guides/hot")
    public ResponseDTO<List<BehaviorGuideDTO>> getHotGuides(@RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<BehaviorGuideDTO> guides = behaviorGuideService.getHotGuides(limit);
            return ResponseDTO.success(guides, "加载成功");
        } catch (Exception e) {
            return ResponseDTO.fail(ResponseCode.SERVER_ERROR, "加载失败，请重试");
        }
    }

    /**
     * 获取个性化推荐指南
     */
    @GetMapping("/behavior-guides/recommend")
    public ResponseDTO<List<BehaviorGuideDTO>> getRecommendGuides(@RequestParam(defaultValue = "10") Integer limit) {
        try {
            Long userId = getCurrentUserId(); // 假设从会话中获取用户ID
            List<BehaviorGuideDTO> guides = behaviorGuideService.getRecommendGuides(userId, limit);
            return ResponseDTO.success(guides, "加载成功");
        } catch (Exception e) {
            return ResponseDTO.fail(ResponseCode.SERVER_ERROR, "加载失败，请重试");
        }
    }

    /**
     * 获取行为百科
     */
    @GetMapping("/behavior-wiki/{name}")
    public ResponseDTO<BehaviorWikiDTO> getBehaviorWiki(@PathVariable("name") String behaviorName) {
        try {
            BehaviorWikiDTO wiki = behaviorGuideService.getBehaviorWiki(behaviorName);
            if (wiki == null) {
                return ResponseDTO.fail(ResponseCode.NOT_FOUND, "该行为百科条目已下架");
            }
            return ResponseDTO.success(wiki, "加载成功");
        } catch (Exception e) {
            return ResponseDTO.fail(ResponseCode.SERVER_ERROR, "加载失败，请重试");
        }
    }

    /**
     * 获取搜索建议
     */
    @GetMapping("/behavior-search/suggestions")
    public ResponseDTO<List<String>> getSearchSuggestions(@RequestParam String prefix, @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<String> suggestions = behaviorGuideService.getSearchSuggestions(prefix, limit);
            return ResponseDTO.success(suggestions, "加载成功");
        } catch (Exception e) {
            return ResponseDTO.fail(ResponseCode.SERVER_ERROR, "加载失败，请重试");
        }
    }

    /**
     * 更新浏览时长
     */
    @PostMapping("/behavior-guides/{id}/duration")
    public ResponseDTO<Boolean> updateViewDuration(@PathVariable("id") Long guideId, @RequestParam Integer duration) {
        try {
            Long userId = getCurrentUserId();
            if (userId != null) {
                behaviorGuideService.updateViewDuration(userId, guideId, duration);
            }
            return ResponseDTO.success(true, "更新成功");
        } catch (Exception e) {
            return ResponseDTO.fail(ResponseCode.SERVER_ERROR, "更新失败，请重试");
        }
    }

    // 辅助方法：获取当前登录用户ID
    private Long getCurrentUserId() {
        // 这里只是示例，实际应该从会话或JWT中获取用户ID
        // 例如：return SecurityContextHolder.getContext().getAuthentication().getPrincipal().getUserId();
        return null; // 未登录返回null
    }

    // 辅助方法：检查关键词是否包含敏感词
    private boolean containsSensitiveWords(String keyword) {
        // 这里只是示例，实际应该调用敏感词过滤服务
        // 敏感词库应该从配置或数据库中加载
        List<String> sensitiveWords = List.of("敏感词1", "敏感词2"); // 示例敏感词
        return sensitiveWords.stream().anyMatch(keyword::contains);
    }

    // 辅助方法：检查关键词是否包含恶意代码
    private boolean containsMaliciousCode(String keyword) {
        // 简单的SQL注入和XSS攻击检测
        String lowerKeyword = keyword.toLowerCase();
        // SQL注入检测
        List<String> sqlInjectionPatterns = List.of("select ", "insert ", "update ", "delete ", "drop ", "truncate ", "exec ");
        // XSS攻击检测
        List<String> xssPatterns = List.of("<script>", "</script>", "<iframe>", "</iframe>", "javascript:", "onload=", "onerror=");
        
        return sqlInjectionPatterns.stream().anyMatch(lowerKeyword::contains) ||
               xssPatterns.stream().anyMatch(lowerKeyword::contains);
    }
}